package rejeev.viewer;

import rejeev.tracer.util.StringUtil;

import java.io.*;
import java.util.*;
import java.util.logging.Logger;

/**
 * Created with IntelliJ IDEA.
 * User: rejeev
 * Date: 10/19/13
 */

public class XmlFormatter {
    private BufferedReader bufferedReader;
    private static final Logger LOGGER = Logger.getLogger(XmlFormatter.class.getName());
    private Map<String, BufferedWriter> bufferedWriterMap = new HashMap<String, BufferedWriter>();
    private String fileName;
    private String directoryName;

    public static void main(String[] args) throws Exception {
        String filePath = args[0];
        new XmlFormatter().process(filePath);
    }

    public void process(String filePath) throws Exception {
        File file = new File(filePath);
        fileName = file.getName();
        fileName = stripExtension(fileName);
        directoryName = file.getParent();
        bufferedReader = new BufferedReader(new FileReader(file));
        String line = bufferedReader.readLine();
        String nextLine = bufferedReader.readLine();
        while (line != null){
            boolean toSkipNextLine = false;
            try {
                toSkipNextLine = processLine(line, nextLine);
            } catch (Exception e) {
                System.out.println("processing of line failed: " + line + " next line: " + nextLine);
                e.printStackTrace();
            }
            if(toSkipNextLine){
                line = bufferedReader.readLine();
                nextLine = bufferedReader.readLine();
            }else {
                line = nextLine;
                nextLine = bufferedReader.readLine();
            }
        }
        bufferedReader.close();
        for(BufferedWriter writer : bufferedWriterMap.values()){
            writer.close();
        }
        LOGGER.info("Completed processing");
    }

    private boolean processLine(String line, String nextLine) throws Exception {
        String[] split = line.split(" *<", 2);
        String threadName = split[0];
        threadName = StringUtil.replaceSpecialCharacters(threadName);
        String methodName = line.substring(threadName.length());
        boolean emptyMethod = emptyMethod(line, nextLine);
        if(emptyMethod) methodName = embedClosingTag(methodName);
        methodName = convertInit(methodName);
        BufferedWriter bufferedWriter = bufferedWriterMap.get(threadName);
        if(bufferedWriter == null){
            LOGGER.info("Start processing thread " + threadName);
            bufferedWriter = new BufferedWriter(new FileWriter(directoryName + "/" + threadName + "-" + fileName + ".xml"));
            bufferedWriterMap.put(threadName, bufferedWriter);
        }
        bufferedWriter.write(methodName);
        bufferedWriter.newLine();
        return emptyMethod;
    }

    private String convertInit(String methodName){
        methodName = methodName.replace("<init>", "init");
        methodName = methodName.replace("<clinit>", "clinit");
        return methodName;
    }

    private String stripExtension(String name){
        int index = name.lastIndexOf('.');
        return name.substring(0, index);
    }

    private String embedClosingTag(String line){
        return line.substring(0, line.length()-1) + "/>";
    }

    private boolean emptyMethod(String line, String nextLine){
        if(nextLine == null) return false;
        if(nextLine.length() < line.length()) return false;
        int index = line.indexOf("<");
        return line.substring(index+1).equals(nextLine.substring(index+2));
    }
}
